#include <jni.h>
#include <GLES/gl.h>
#include <GLES2/gl2.h>
#include "CCGLPrimitivesDef.h"

//引入glm头文件
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <glm/mat4x4.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/ext/matrix_transform.hpp>
#include <glm/ext/matrix_clip_space.hpp>

//引入stb_image
#define STB_IMAGE_IMPLEMENTATION
extern "C"{
    #include "stb_image.h"
}
//立方体旋转角度
float m_angle =0.0f;
GLuint m_texID;
int width, height, nrChannels;
extern "C"
JNIEXPORT void JNICALL
Java_com_itfitness_opengldemo_GLRender_ndkLoadGLTexTureID(JNIEnv *env, jobject thiz,
                                                          jstring file_name) {
    glEnable(GL_TEXTURE_2D);
    glGenTextures(1,&m_texID);//产生纹理索引
    glBindTexture(GL_TEXTURE_2D,m_texID);//绑定纹理索引，之后的操作都针对当前纹理索引

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);//指当纹理图象被使用到一个大于它的形状上时
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);//指当纹理图象被使用到一个小于或等于它的形状上时
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    const char* fileName = env->GetStringUTFChars(file_name,0);
    // 让图像正过来（如果不加图像是倒过来的）
    stbi_set_flip_vertically_on_load(true);
    // 加载并生成纹理
    unsigned char *data = stbi_load(fileName, &width, &height, &nrChannels, 0);
    if (data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    }
    // 释放资源
    env->ReleaseStringUTFChars(file_name, fileName);
    stbi_image_free(data);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_itfitness_opengldemo_GLRender_ndkInitGL(JNIEnv *env, jobject thiz) {
    //清空颜色
    glClearColor(0.0,0,0,1.0);
    //清空深度缓存
    glClearDepthf(1.0);
    //开启深度测试
    glEnable(GL_DEPTH_TEST);
    //什么情况下使用深度测试
    glDepthFunc(GL_LEQUAL);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_itfitness_opengldemo_GLRender_ndkPaintGL(JNIEnv *env, jobject thiz) {
    //清空颜色缓冲区或深度缓冲区
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    //加载模型视图矩阵
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glCullFace(GL_BACK);

    //定义立方体顶点
    CCFloat5 cubeVert[] = {
            { -1.0f, 1.0f, 0.0f,    0,  1 },
            {  1.0f,1.0f, 0.0f,   1,  1 },
            {  -1.0f,-1.0f, 0.0f,    0,  0 },
            {  1.0f, -1.0f, 0.0f,    1,  0 },
    };

    glBindTexture(GL_TEXTURE_2D,m_texID);
    //启动一组顶点坐标
    glEnableClientState(GL_VERTEX_ARRAY);
    //启动TEXTURE
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    // 指定绘制的定点数组
    // 第一个参数：绘制几个点（这里其实就是CCFloat5中的前三个点x,y,z）
    // 第二个参数：类型为float
    // 第三个参数：第一个点到第二个点之间的步长（也就是结构体的长度）
    // 第四个参数：绘制数据的地址
    glVertexPointer(3,GL_FLOAT,sizeof(CCFloat5),cubeVert);
    // 指定绘制的定点数组
    // 第一个参数：绘制几个点（这里其实就是CCFloat5中的后两个点u,v）
    // 第二个参数：类型为float
    // 第三个参数：第一个点到第二个点之间的步长（也就是结构体的长度）
    // 第四个参数：绘制数据的地址
    glTexCoordPointer(2,GL_FLOAT,sizeof(CCFloat5),&cubeVert[0].u);

    glm::mat4x4  cubeMat;
    //平移矩阵
    glm::mat4x4  cubeTransMat = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -0.5));
    //旋转矩阵
    glm::mat4x4  cubeRotMat = glm::rotate(glm::mat4(1.0f),m_angle,glm::vec3(0.5f, 0.5f, 1.0) );
    //缩放矩阵
    glm::mat4x4  cubeScaleMat = glm::scale(glm::mat4(1.0f),glm::vec3(0.5f, 0.5f, 0.5) );
    cubeMat = cubeTransMat * cubeRotMat * cubeScaleMat;

    //加载矩阵
    glLoadMatrixf(glm::value_ptr(cubeMat));

    // 绘制四边形
    glDrawArrays(GL_TRIANGLE_STRIP,0,4);

    //关闭一组顶点坐标
    glDisableClientState(GL_VERTEX_ARRAY);
    //关闭TEXTURE
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_itfitness_opengldemo_GLRender_ndkResizeGL(JNIEnv *env, jobject thiz, jint width,
                                                   jint height) {
    //设置窗口大小
    glViewport(0,0,width,height);
    //投影矩阵
    glMatrixMode(GL_PROJECTION);
    //重置投影矩阵
    glLoadIdentity();
    //摄像机
    glOrthof(-1,1,-1,1,0,1000);

    //添加模型视图矩阵
    glMatrixMode(GL_MODELVIEW);
    //重置当前指定的矩阵为单位矩阵
    glLoadIdentity();
}
